import React, { useRef, useEffect, useState } from 'react'

interface TrendChartProps {
  data: {
    dates: string[]
    values: number[]
    highlightPoint: {
      date: string
      value: number
      label: string
    }
    total?: number
  }
}

const TrendChart: React.FC<TrendChartProps> = ({ data }) => {
  const canvasRef = useRef<HTMLCanvasElement>(null)
  const containerRef = useRef<HTMLDivElement>(null)
  const animationProgress = useRef(0)
  const animationFrameId = useRef<number | null>(null)
  const [hoveredPoint, setHoveredPoint] = useState<{ x: number; y: number; value: number; date: string; index: number } | null>(null)
  const [mousePos, setMousePos] = useState<{ x: number; y: number } | null>(null)

  useEffect(() => {
    const canvas = canvasRef.current
    if (!canvas) return

    const ctx = canvas.getContext('2d')
    if (!ctx) return

    // 设置画布大小
    const rect = canvas.getBoundingClientRect()
    canvas.width = rect.width * window.devicePixelRatio
    canvas.height = rect.height * window.devicePixelRatio
    ctx.scale(window.devicePixelRatio, window.devicePixelRatio)

    // 动画函数
    const animate = () => {
    // 清除画布
    ctx.clearRect(0, 0, rect.width, rect.height)

    // 图表配置
    const padding = { top: 40, right: 40, bottom: 60, left: 60 }
    const chartWidth = rect.width - padding.left - padding.right
    const chartHeight = rect.height - padding.top - padding.bottom

    // 数据处理
      const maxValue = Math.max(...data.values, 0)
      const minValue = Math.min(...data.values, 0)
      const valueRange = maxValue - minValue || 1 // 避免除零错误

    // 绘制网格线
    ctx.strokeStyle = '#f0f0f0'
    ctx.lineWidth = 1

    // 水平网格线
    for (let i = 0; i <= 5; i++) {
      const y = padding.top + (chartHeight / 5) * i
      ctx.beginPath()
      ctx.moveTo(padding.left, y)
      ctx.lineTo(padding.left + chartWidth, y)
      ctx.stroke()
    }

    // 垂直网格线
    for (let i = 0; i <= data.dates.length - 1; i++) {
      const x = padding.left + (chartWidth / (data.dates.length - 1)) * i
      ctx.beginPath()
      ctx.moveTo(x, padding.top)
      ctx.lineTo(x, padding.top + chartHeight)
      ctx.stroke()
    }

      // 绘制渐变背景（带动画）
    const gradient = ctx.createLinearGradient(0, padding.top, 0, padding.top + chartHeight)
    gradient.addColorStop(0, 'rgba(59, 130, 246, 0.1)')
    gradient.addColorStop(1, 'rgba(59, 130, 246, 0.01)')

      // 计算动画进度下的数据点
      const animatedPoints = data.values.map((value, index) => {
        const x = padding.left + (chartWidth / Math.max(data.values.length - 1, 1)) * index
        const normalizedValue = valueRange > 0 ? ((value - minValue) / valueRange) : 0.5
        const y = padding.top + chartHeight - normalizedValue * chartHeight
        return { x, y, value }
      })

      // 绘制填充区域（带动画）
    ctx.beginPath()
      animatedPoints.forEach((point, index) => {
      if (index === 0) {
          ctx.moveTo(point.x, point.y)
        } else {
          // 根据动画进度决定是否绘制这一点
          const pointProgress = Math.min(1, animationProgress.current * data.values.length - index)
          if (pointProgress > 0) {
            const prevPoint = animatedPoints[index - 1]
            const currentX = prevPoint.x + (point.x - prevPoint.x) * pointProgress
            const currentY = prevPoint.y + (point.y - prevPoint.y) * pointProgress
            ctx.lineTo(currentX, currentY)
      } else {
            ctx.lineTo(point.x, point.y)
          }
      }
    })

    // 填充区域
      if (animatedPoints.length > 0) {
        const lastPoint = animatedPoints[animatedPoints.length - 1]
        const lastX = animatedPoints[0].x + (lastPoint.x - animatedPoints[0].x) * animationProgress.current
        ctx.lineTo(lastX, padding.top + chartHeight)
    ctx.lineTo(padding.left, padding.top + chartHeight)
    ctx.closePath()
    ctx.fillStyle = gradient
    ctx.fill()
      }

      // 绘制折线（带动画）
    ctx.beginPath()
      animatedPoints.forEach((point, index) => {
      if (index === 0) {
          ctx.moveTo(point.x, point.y)
        } else {
          const pointProgress = Math.min(1, animationProgress.current * data.values.length - index)
          if (pointProgress > 0) {
            const prevPoint = animatedPoints[index - 1]
            const currentX = prevPoint.x + (point.x - prevPoint.x) * pointProgress
            const currentY = prevPoint.y + (point.y - prevPoint.y) * pointProgress
            ctx.lineTo(currentX, currentY)
      } else {
            ctx.lineTo(point.x, point.y)
          }
      }
    })
    ctx.strokeStyle = '#3b82f6'
    ctx.lineWidth = 2
    ctx.stroke()

      // 绘制数据点（带动画）
      animatedPoints.forEach((point, index) => {
        const pointProgress = Math.min(1, animationProgress.current * data.values.length - index)
        if (pointProgress > 0) {
          const opacity = pointProgress
          const scale = 0.5 + pointProgress * 0.5
          
          // 如果鼠标悬停在此点上，放大显示
          const isHovered = hoveredPoint?.index === index
          const pointScale = isHovered ? scale * 1.5 : scale
          const pointRadius = isHovered ? 6 : 4

      ctx.beginPath()
          ctx.arc(point.x, point.y, pointRadius * pointScale, 0, 2 * Math.PI)
          ctx.fillStyle = isHovered 
            ? `rgba(59, 130, 246, 1)` 
            : `rgba(59, 130, 246, ${opacity})`
      ctx.fill()
      ctx.strokeStyle = '#ffffff'
          ctx.lineWidth = isHovered ? 3 : 2
          ctx.stroke()
          
          // 悬停时绘制连接线
          if (isHovered) {
            ctx.beginPath()
            ctx.moveTo(point.x, padding.top)
            ctx.lineTo(point.x, padding.top + chartHeight)
            ctx.strokeStyle = 'rgba(59, 130, 246, 0.3)'
            ctx.lineWidth = 1
            ctx.setLineDash([5, 5])
      ctx.stroke()
            ctx.setLineDash([])
          }
        }
      })
      
      // 绘制悬停提示框
      if (hoveredPoint && mousePos) {
        const tooltipWidth = 120
        const tooltipHeight = 60
        const tooltipX = Math.min(
          Math.max(hoveredPoint.x - tooltipWidth / 2, padding.left),
          rect.width - padding.right - tooltipWidth
        )
        const tooltipY = Math.max(hoveredPoint.y - tooltipHeight - 20, padding.top)
        const radius = 8
        
        // 绘制圆角矩形背景
        ctx.fillStyle = 'rgba(0, 0, 0, 0.8)'
        ctx.beginPath()
        ctx.moveTo(tooltipX + radius, tooltipY)
        ctx.lineTo(tooltipX + tooltipWidth - radius, tooltipY)
        ctx.quadraticCurveTo(tooltipX + tooltipWidth, tooltipY, tooltipX + tooltipWidth, tooltipY + radius)
        ctx.lineTo(tooltipX + tooltipWidth, tooltipY + tooltipHeight - radius)
        ctx.quadraticCurveTo(tooltipX + tooltipWidth, tooltipY + tooltipHeight, tooltipX + tooltipWidth - radius, tooltipY + tooltipHeight)
        ctx.lineTo(tooltipX + radius, tooltipY + tooltipHeight)
        ctx.quadraticCurveTo(tooltipX, tooltipY + tooltipHeight, tooltipX, tooltipY + tooltipHeight - radius)
        ctx.lineTo(tooltipX, tooltipY + radius)
        ctx.quadraticCurveTo(tooltipX, tooltipY, tooltipX + radius, tooltipY)
        ctx.closePath()
        ctx.fill()
        
        // 绘制文字
        ctx.fillStyle = '#ffffff'
        ctx.font = 'bold 12px Arial'
        ctx.textAlign = 'center'
        ctx.fillText(
          new Date(hoveredPoint.date).toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' }),
          tooltipX + tooltipWidth / 2,
          tooltipY + 20
        )
        ctx.font = '11px Arial'
        ctx.fillText(
          `数值: ${hoveredPoint.value}`,
          tooltipX + tooltipWidth / 2,
          tooltipY + 40
        )
      }

      // 绘制高亮点（带延迟动画）
      if (animationProgress.current > 0.5 && data.highlightPoint.value > 0) {
        const highlightIndex = Math.floor(data.values.length / 2)
        const highlightX = padding.left + (chartWidth / Math.max(data.values.length - 1, 1)) * highlightIndex
        const normalizedHighlightValue = valueRange > 0 ? ((data.highlightPoint.value - minValue) / valueRange) : 0.5
        const highlightY = padding.top + chartHeight - normalizedHighlightValue * chartHeight
        const highlightProgress = Math.min(1, (animationProgress.current - 0.5) * 2)

    // 高亮点
    ctx.beginPath()
        ctx.arc(highlightX, highlightY, 6 * highlightProgress, 0, 2 * Math.PI)
        ctx.fillStyle = `rgba(239, 68, 68, ${highlightProgress})`
    ctx.fill()
    ctx.strokeStyle = '#ffffff'
    ctx.lineWidth = 3
    ctx.stroke()

    // 高亮标签
        if (highlightProgress > 0.7) {
          ctx.fillStyle = `rgba(55, 65, 81, ${(highlightProgress - 0.7) / 0.3})`
    ctx.font = '12px Arial'
    ctx.textAlign = 'center'
    ctx.fillText(data.highlightPoint.date, highlightX, highlightY - 15)
    ctx.fillText(data.highlightPoint.label, highlightX, highlightY - 30)
        }
      }

    // 绘制 X 轴标签
    ctx.fillStyle = '#6b7280'
    ctx.font = '11px Arial'
    ctx.textAlign = 'center'
    data.dates.forEach((date, index) => {
      const x = padding.left + (chartWidth / (data.dates.length - 1)) * index
      const formattedDate = new Date(date).toLocaleDateString('zh-CN', { 
        month: '2-digit', 
        day: '2-digit' 
      })
      ctx.fillText(formattedDate, x, padding.top + chartHeight + 20)
    })

    // 绘制 Y 轴标签
    ctx.textAlign = 'right'
    for (let i = 0; i <= 5; i++) {
      const value = minValue + (valueRange / 5) * i
      const y = padding.top + chartHeight - (chartHeight / 5) * i
      ctx.fillText(Math.round(value).toString(), padding.left - 10, y + 4)
    }

      // 更新动画进度
      if (animationProgress.current < 1) {
        animationProgress.current += 0.015
        animationFrameId.current = requestAnimationFrame(animate)
      } else {
        // 动画完成后，确保绘制完整图形
        animationProgress.current = 1
      }
    }

    // 重置动画进度并开始动画
    animationProgress.current = 0
    animationFrameId.current = requestAnimationFrame(animate)

    return () => {
      if (animationFrameId.current !== null) {
        cancelAnimationFrame(animationFrameId.current)
      }
    }
  }, [data, hoveredPoint, mousePos])

  // 处理鼠标移动事件
  useEffect(() => {
    const canvas = canvasRef.current
    const container = containerRef.current
    if (!canvas || !container) return

    const handleMouseMove = (e: MouseEvent) => {
      const rect = canvas.getBoundingClientRect()
      const padding = { top: 40, right: 40, bottom: 60, left: 60 }
      const chartWidth = rect.width - padding.left - padding.right
      const chartHeight = rect.height - padding.top - padding.bottom
      
      const x = e.clientX - rect.left
      const y = e.clientY - rect.top
      
      setMousePos({ x, y })
      
      // 检查鼠标是否在图表区域内
      if (x >= padding.left && x <= rect.width - padding.right && 
          y >= padding.top && y <= rect.height - padding.bottom) {
        // 找到最近的数据点
        const pointIndex = Math.round(((x - padding.left) / chartWidth) * (data.values.length - 1))
        const clampedIndex = Math.max(0, Math.min(pointIndex, data.values.length - 1))
        
        const pointX = padding.left + (chartWidth / Math.max(data.values.length - 1, 1)) * clampedIndex
        const maxValue = Math.max(...data.values, 0)
        const minValue = Math.min(...data.values, 0)
        const valueRange = maxValue - minValue || 1
        const normalizedValue = valueRange > 0 ? ((data.values[clampedIndex] - minValue) / valueRange) : 0.5
        const pointY = padding.top + chartHeight - normalizedValue * chartHeight
        
        // 检查鼠标是否在数据点附近（20px范围内）
        const distance = Math.sqrt(Math.pow(x - pointX, 2) + Math.pow(y - pointY, 2))
        if (distance < 20) {
          setHoveredPoint({
            x: pointX,
            y: pointY,
            value: data.values[clampedIndex],
            date: data.dates[clampedIndex],
            index: clampedIndex
          })
        } else {
          setHoveredPoint(null)
        }
      } else {
        setHoveredPoint(null)
      }
    }

    const handleMouseLeave = () => {
      setHoveredPoint(null)
      setMousePos(null)
    }

    container.addEventListener('mousemove', handleMouseMove)
    container.addEventListener('mouseleave', handleMouseLeave)

    return () => {
      container.removeEventListener('mousemove', handleMouseMove)
      container.removeEventListener('mouseleave', handleMouseLeave)
    }
  }, [data])

  return (
    <div ref={containerRef} className="w-full h-80 relative cursor-crosshair">
      <canvas
        ref={canvasRef}
        className="w-full h-full"
        style={{ display: 'block' }}
      />
    </div>
  )
}

export default TrendChart


